/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.ranger.plugin.util; import java.io.IOException; import java.util.Map; import javax.crypto.Cipher; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.PBEKeySpec; import javax.crypto.spec.PBEParameterSpec; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.sun.jersey.core.util.Base64; public class PasswordUtils { private static final Logger LOG = LoggerFactory.getLogger(PasswordUtils.class); private static String CRYPT_ALGO = null; private static String password = null; private static char[] ENCRYPT_KEY = null; private static byte[] SALT = null; private static int ITERATION_COUNT = 0; private static final String LEN_SEPARATOR_STR = ":"; public static final String DEFAULT_CRYPT_ALGO = "PBEWithMD5AndDES"; public static final String DEFAULT_ENCRYPT_KEY = "tzL1AKl5uc4NKYaoQ4P3WLGIBFPXWPWdu1fRm9004jtQiV"; public static final String DEFAULT_SALT = "f77aLYLo"; public static final int DEFAULT_ITERATION_COUNT = 1000; public static String encryptPassword(String aPassword) throws IOException { setPropertiesvalues(aPassword); Map<String, String> env = System.getenv(); String encryptKeyStr = env.get("ENCRYPT_KEY"); char[] encryptKey; if (encryptKeyStr == null) { encryptKey=ENCRYPT_KEY; }else{ encryptKey=encryptKeyStr.toCharArray(); } String saltStr = env.get("ENCRYPT_SALT"); byte[] salt; if (saltStr == null) { salt = SALT; }else{ salt=saltStr.getBytes(); } String ret = null; String strToEncrypt = null; if (aPassword == null) { strToEncrypt = ""; } else { strToEncrypt = aPassword.length() + LEN_SEPARATOR_STR + password; } try { Cipher engine = Cipher.getInstance(CRYPT_ALGO); PBEKeySpec keySpec = new PBEKeySpec(encryptKey); SecretKeyFactory skf = SecretKeyFactory.getInstance(CRYPT_ALGO); SecretKey key = skf.generateSecret(keySpec); engine.init(Cipher.ENCRYPT_MODE, key, new PBEParameterSpec(salt, ITERATION_COUNT)); byte[] encryptedStr = engine.doFinal(strToEncrypt.getBytes()); ret = new String(Base64.encode(encryptedStr)); } catch(Throwable t) { LOG.error("Unable to encrypt password due to error", t); throw new IOException("Unable to encrypt password due to error", t); } return ret; } public static void setPropertiesvalues(String aPassword) { String[] crypt_algo_array = null; if (aPassword.contains(",")) { crypt_algo_array = aPassword.split(","); } if (crypt_algo_array != null && crypt_algo_array.length > 1) { CRYPT_ALGO = crypt_algo_array[0]; ENCRYPT_KEY = crypt_algo_array[1].toCharArray(); SALT = crypt_algo_array[2].getBytes(); ITERATION_COUNT = Integer.parseInt(crypt_algo_array[3]); password = crypt_algo_array[4]; } else { CRYPT_ALGO = DEFAULT_CRYPT_ALGO; ENCRYPT_KEY = DEFAULT_ENCRYPT_KEY.toCharArray(); SALT = DEFAULT_SALT.getBytes(); ITERATION_COUNT = DEFAULT_ITERATION_COUNT; } } public static String decryptPassword(String aPassword) throws IOException { setPropertiesvalues(aPassword); String ret = null; Map<String, String> env = System.getenv(); String encryptKeyStr = env.get("ENCRYPT_KEY"); char[] encryptKey; if (encryptKeyStr == null) { encryptKey=ENCRYPT_KEY; }else{ encryptKey=encryptKeyStr.toCharArray(); } String saltStr = env.get("ENCRYPT_SALT"); byte[] salt; if (saltStr == null) { salt = SALT; }else{ salt=saltStr.getBytes(); } try { byte[] decodedPassword = Base64.decode(password); Cipher engine = Cipher.getInstance(CRYPT_ALGO); PBEKeySpec keySpec = new PBEKeySpec(encryptKey); SecretKeyFactory skf = SecretKeyFactory.getInstance(CRYPT_ALGO); SecretKey key = skf.generateSecret(keySpec); engine.init(Cipher.DECRYPT_MODE, key,new PBEParameterSpec(salt, ITERATION_COUNT)); String decrypted = new String(engine.doFinal(decodedPassword)); int foundAt = decrypted.indexOf(LEN_SEPARATOR_STR); if (foundAt > -1) { if (decrypted.length() > foundAt) { ret = decrypted.substring(foundAt+1); } else { ret = ""; } } else { ret = null; } } catch(Throwable t) { LOG.error("Unable to decrypt password due to error", t); throw new IOException("Unable to decrypt password due to error", t); } return ret; } }